<template>
    <QilinDialog v-model:dialogConfig="dialogConfig" @handleClose="handleCloseDialog">
        <template v-if="previewConfig.type === 'image' ">
            <ViewImage :imageList="getImageList(previewConfig)"></ViewImage>
        </template>
        <template v-else-if="previewConfig.type === 'word'">
            <!-- <div ref="wordRef" class="beauty-scrollbar-y" style="height:400px;"></div> -->
             <VueOfficeDocx
                :src="previewConfig.url"
                class="beauty-scrollbar-y"
                style="height:400px;"
                @rendered="renderWord"
                @error="handleWordError"
             ></VueOfficeDocx>
        </template>
        <template v-else-if="previewConfig.type === 'excel'">
            <div ref="excelRef" class="beauty-scrollbar-y flex-column" style="height:400px;">
                <div>
                    <el-radio-group size="small" v-model="excelData.sheetNameActive"
                        @change="getSheetNameTable"
                    >
                        <el-radio-button v-for="(item,index) in excelData.sheetNames"
                            :key="index" :value="item" :label="item"
                        ></el-radio-button>
                    </el-radio-group>
                </div>
                <div class="qilin-mt-3 beauty-scrollbar-y" style="border: 1px solid #a0a0a0;flex:1;">
                    <div v-html="excelData.SheetActiveTable" class="qilin-py-5 qilin-px-8"></div>
                </div>
             </div>
        </template>
        <template v-else-if="previewConfig.type === 'pdf'">
            <iframe :src="previewConfig.url" frameborder="0" width="100%" height="400"></iframe>
        </template>
        <template v-else-if="previewConfig.type === 'pptx'">
            <VueOfficePPtx
                :src="previewConfig.url"
                style="width:100%;height:400px;"
                class="beauty-scrollbar-y"
                @rendered="renderPptx"
                @error="handlePptxError"
            ></VueOfficePPtx>
        </template>
        <template v-else-if="previewConfig.type === 'video'">
            <video ref="videoRef" width="100%" height="400" controls>
                <source :src="previewConfig.url" type="video/mp4">
            </video>
        </template>
        <div class="qilin-previewFiles-footer qilin-py-4 qilin-radius-default">
            <el-icon @click="prev()"><ArrowLeftBold /></el-icon>
            <div class="qilin-previewFiles-footer-list">
                <div class="qilin-previewFiles-footer-list-item qilin-mx-2" v-for="item in previewConfig.fileList"
                    :key="item[fileOptions.serverUrl || 'fileName']"
                    :class="fileIp + item[fileOptions.serverUrl || 'fileName'] === currentUrl ? 'is-active' : '' "
                    @click="renderPreview(item)"
                >
                    <img class="qilin-wh-100" :src="getImageUrl(item)" alt="">
                </div>
            </div>
            <el-icon @click="next()"><ArrowRightBold /></el-icon>
        </div>
    </QilinDialog>
</template>

<script setup>
/**
 * 组件介绍：全局预览各类型文件
 * 功能描述：支持在线预览docx、pdf、excel、pptx、视频、图片等文件
 * 
 * @author Qilin
 * @CreateDate 2025-01-20 创建日期
 * @lastUpdatePerson Qilin 最后修改人
 * @lastUpdateDate 2025-06-05 最后修改日期
 */

import VueOfficeDocx from "@vue-office/docx";
// import {renderAsync} from "docx-preview";
import * as XLSX from "xlsx";
import VueOfficePPtx from "@vue-office/pptx";
import ViewImage from "./viewImage/index.vue";
import {fileIp,fileOptions} from "@/setting.js";
import {getFilesBlobData} from "@/api/index.js";
import {downloadFileData} from "@/utils/common.js";


/*
    响应式选项区域
*/
const propsValue = defineProps({
    fileList:Array
});


/*
    数据变量定义区域
*/
let previewConfig=reactive({
    type:"", //文件类型
    url:"", //文件地址
    fileList:[], //文件列表
    fileName:"", //文件名
});
let currentUrl = ref(""); //当前预览的文件url
const wordRef = ref(null); //获取word展示区域DOM
const excelRef=ref(null); //获取excel展示区域DOM
const excelData=reactive({ // excel预览配置项
    workbook:{}, //数据
    sheetNames:[], //表名称集合
    sheetNameActive:"", //激活项
    SheetActiveTable:"" //当前激活表格
});


/*
    计算属性等代码区域
*/
const getImageList = computed(()=>{
    return (obj)=>{
        return [{
            fileName:obj.url
        }]
    }
});
// 根据文件链接类型返回相关形式图片
const getImageUrl=computed(()=>{
    return (item)=>{
        const index=item[fileOptions.serverOriginalName || "originalFilename" ]?.lastIndexOf(".");
        const fileType=item[fileOptions.serverOriginalName || "originalFilename" ]?.slice(index+1).toLowerCase();
        if(["png","jpg","jpeg","gif"].includes(fileType)){
            return fileIp+item[fileOptions.serverUrl || "fileName"];
        }else if(fileType === "pdf"){
            return new URL("@/assets/images/pdf.svg",import.meta.url).href;
        }else if(fileType === "doc" || fileType === "docx"){
            return new URL("@/assets/images/doc.svg",import.meta.url).href;
        }else if(fileType === "xls" || fileType === "xlsx"){
            return new URL("@/assets/images/excel.svg",import.meta.url).href;
        }else{
            return new URL("@/assets/images/file.png",import.meta.url).href;
        };
    };
});


/*
    逻辑脚本代码区域
*/
// 初始化渲染预览
const renderPreview=(file,fileList)=>{
    // console.log(file,fileList);
    const index=file[fileOptions.serverOriginalName || "originalFilename" ].lastIndexOf(".");
    const fileType=file[fileOptions.serverOriginalName || "originalFilename" ].slice(index+1).toLowerCase();
    previewConfig.url = currentUrl.value = fileIp + file[fileOptions.serverUrl || "fileName"];
    previewConfig.fileName = file[fileOptions.serverName || "originalFilename"];
    if(["png","jpg","jpeg","gif"].includes(fileType)){
        previewConfig.type = "image";
    }else if(["doc","docx"].includes(fileType)){
        previewConfig.type = "word";
        // getFilesBlobData(null,"blob",{
        //     resource:previewConfig.url
        // }).then((res)=>{
        //     if(res){
        //         renderAsync(res,wordRef.value);
        //     }else{
        //         ElMessage({
        //             message:"文件预览失败",
        //             type:"error"
        //         });
        //     }
        // });
    }else if(["xlsx","xls"].includes(fileType)){
        previewConfig.type = "excel";
        getFilesBlobData({
            "Content-Type" : "application/vnd.ms-excel;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
        },"arraybuffer",{
            resource:previewConfig.url
        }).then((res)=>{
            if(res){
                const workbook=XLSX.read(new Uint8Array(res),{type:"array"});
                const sheetNames=workbook.SheetNames; //工作表名称集合
                excelData.workbook=workbook;
                excelData.sheetNames=sheetNames;
                excelData.sheetNameActive=sheetNames[0];
                getSheetNameTable(sheetNames[0]);
            }else{
                ElMessage({
                    message:"文件预览失败",
                    type:"error"
                });
            }
        });
    }else if(fileType === "pdf"){
        previewConfig.type = "pdf";
    }else if(["ppt","pptx"].includes(fileType)){
        previewConfig.type = "pptx";
    }else if(["avi","wmv","mp4","mov","3gp","rmvb","flv"].includes(fileType)){
        previewConfig.type = "video";
    }
    if(fileList){
        previewConfig.fileList = fileList || [];
        dialogConfig.isShow = true;
    }
};
// 点击左箭头图标事件监听
const prev=()=>{
    const index=previewConfig.fileList.findIndex((item)=>{
        return fileIp + item[fileOptions.serverUrl || "fileName"] === currentUrl.value;
    });
    if(index === 0){ // 若当前文件是第一项时
        renderPreview(previewConfig.fileList[previewConfig.fileList.length-1]);
    }else{
        renderPreview(previewConfig.fileList[index-1]);
    };
};
// 点击右箭头图标事件监听
const next=()=>{
    const index=previewConfig.fileList.findIndex((item)=>{
        return fileIp + item[fileOptions.serverUrl || "fileName"] === currentUrl.value;
    });
    if(index === previewConfig.fileList.length-1){ // 若当前文件是最后一项时
        renderPreview(previewConfig.fileList[0]);
    }else{
        renderPreview(previewConfig.fileList[index+1]);
    };
};
// 关闭弹窗事件监听
const handleCloseDialog=()=>{
    dialogConfig.isShow = false;
    previewConfig.type = null;
};

/**
 * word相关方法事件
 */
// word文件渲染成功事件监听
const renderWord=()=>{
    // console.log("渲染完成");
};
// word文件渲染失败事件监听
const handleWordError=(err)=>{
    ElMessage({
        message:"暂不支持预览.doc文件",
        type:"warning"
    });
};

/**
 * excel相关方法事件
 */
 function getSheetNameTable(sheetName) {
    try {
        // 获取当前工作表的数据
        const worksheet = excelData.workbook.Sheets[sheetName]
        // 转换为数据  1.json数据有些问题，2.如果是html那么样式需修改
        let htmlData = XLSX.utils.sheet_to_html(worksheet, {header: '', footer: ''})
        htmlData = htmlData === '' ? htmlData : htmlData.replace(/<table/, '<table class="default-table" border="1px solid #ccc" cellpadding="0" cellspacing="0"')
        // 第一行进行改颜色
        htmlData = htmlData === '' ? htmlData : htmlData.replace(/<tr/, '<tr style="background:#b4c9e8"')
        excelData.SheetActiveTable = htmlData
    } catch (e) {
        // 如果工作表没有数据则到这里来处理
        excelData.SheetActiveTable = '<h4 style="text-align: center">' + "暂无内容" + '</h4>'
    }
};
/**
 * pptx相关方法事件
 */
// pptx渲染成功事件监听
const renderPptx=()=>{
    // console.log("渲染完成");
};
// pptx渲染失败事件监听
const handlePptxError=(err)=>{
    // console.log("渲染失败");
};

// 弹窗配置项
const dialogConfig=reactive({
    isShow:false,
    title:"文件预览",
    width:800,
    isHideFooter:false,
    cancelBtnConfig:{
        isShow:false
    },
    confirmBtnConfig:{
        isShow:false
    },
    additionalButton:[
        {
            btnName:"下载",
            btnType:"primary",
            btnClick:()=>{
                // console.log(previewConfig.url,previewConfig.fileName);return;
                downloadFileData(null,"blob",{
                    resource:previewConfig.url
                },true,previewConfig.fileName);
            }
        }
    ]
});


/*
    生命周期等代码区域
*/
defineExpose({
    renderPreview
});


</script>

<style lang="scss" scoped>
.qilin-previewFiles-footer{
    width:100%;
    bottom:0;
    left:0;
    background-color:var(--qilin-color-info);
    position:relative;
    >.el-icon:first-child{
        position:absolute;
        color:#fff;
        font-size:$medium-text-size;
        left:15px;
        top:50%;
        transform:translateY(-50%);
    }
    >.el-icon:last-child{
        position:absolute;
        color:#fff;
        font-size:$medium-text-size;
        right:15px;
        top:50%;
        transform:translateY(-50%);
    }
    >.qilin-previewFiles-footer-list{
        display:flex;
        flex-flow:row nowrap;
        justify-content:center;
        align-items:center;
        overflow:hidden;
        >.qilin-previewFiles-footer-list-item{
            width:32px;
            height:32px;
            border:2px dashed #fff;
            &.is-active{
                border-color:var(--qilin-color-primary);
                // box-shadow: -5px -3px 8px 0px rgba(73, 127, 176, 0.15);
            }
            &:hover{
                border-color:var(--qilin-color-primary);
            }
        }
    }
}

</style>
<style lang="scss">
/**
    word预览组件样式
*/
.docx-wrapper{
    padding:0 30px !important;
}
/**
    pptx预览组件样式
*/
.pptx-preview-wrapper{
    width: 100% !important;
    height:400px !important;
    overflow:auto !important;
    // 兼容火狐浏览器
    scrollbar-width:thin;
    scrollbar-color:var(--qilin-border-color) #fff;
    // 兼容IE浏览器
    scrollbar-darkshadow-color:#fff;
    scrollbar-base-color:var(--qilin-border-color);
    &::-webkit-scrollbar{
        width:5px !important;
    }
    &::-webkit-scrollbar-thumb{
        background-color:var(--qilin-border-color);
        border-radius:5px;
    }
    &::-webkit-scrollbar-track{
        background-color:#fff;
    }
}
</style>
